home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / lists / mint / l_1199 / 1749 < prev    next >
Encoding:
Internet Message Format  |  1994-08-27  |  7.6 KB

  1. Date: Fri, 22 Jul 1994 17:24:38 -0400
  2. From: "Nicholas S Castellano" <entropy@terminator.rs.itd.umich.edu>
  3. To: mint@terminator.rs.itd.umich.edu
  4. Subject: Tsetitimer()
  5.  
  6.  
  7. Here's an implementation of Tsetitimer(), providing interval timers
  8. like the BSD setitimer()/getitimer() system calls.
  9.  
  10.  
  11. diff -u ../old/dos.c ./dos.c
  12. --- ../old/dos.c    Fri Jul 22 03:48:08 1994
  13. +++ ./dos.c    Fri Jul 22 05:53:48 1994
  14. @@ -478,6 +478,211 @@
  15.      return oldalarm;
  16.  }
  17.  
  18. +#define ITIMER_REAL 0
  19. +#define ITIMER_VIRTUAL 1
  20. +#define ITIMER_PROF 2
  21. +
  22. +/*
  23. + * helper function for t_setitimer: this will be called when the ITIMER_REAL
  24. + * timer goes off
  25. + */
  26. +
  27. +static void
  28. +itimer_real_me(p)
  29. +    PROC *p;
  30. +{
  31. +    PROC *real_curproc;
  32. +
  33. +    real_curproc = curproc;
  34. +    curproc = p;
  35. +    if (p->itimer[ITIMER_REAL].interval)
  36. +      p->itimer[ITIMER_REAL].timeout =
  37. +        addtimeout(p->itimer[ITIMER_REAL].interval, itimer_real_me);
  38. +    else
  39. +      p->itimer[ITIMER_REAL].timeout = 0;
  40. +
  41. +    curproc = real_curproc;
  42. +    post_sig(p, SIGALRM);
  43. +}
  44. +
  45. +/*
  46. + * helper function for t_setitimer: this will be called when the ITIMER_VIRTUAL
  47. + * timer goes off
  48. + */
  49. +
  50. +static void
  51. +itimer_virtual_me(p)
  52. +    PROC *p;
  53. +{
  54. +    PROC *real_curproc;
  55. +    long timeleft;
  56. +
  57. +    real_curproc = curproc;
  58. +    curproc = p;
  59. +    timeleft = p->itimer[ITIMER_VIRTUAL].reqtime
  60. +            - (p->systime - p->itimer[ITIMER_VIRTUAL].startsystime);
  61. +    if (timeleft > 0) {
  62. +        p->itimer[ITIMER_VIRTUAL].timeout =
  63. +            addtimeout(timeleft, itimer_virtual_me);
  64. +    } else {
  65. +        timeleft = p->itimer[ITIMER_VIRTUAL].interval;
  66. +        if (timeleft == 0) {
  67. +            p->itimer[ITIMER_VIRTUAL].timeout = 0;
  68. +        } else {
  69. +            p->itimer[ITIMER_VIRTUAL].reqtime = timeleft;
  70. +            p->itimer[ITIMER_VIRTUAL].startsystime = p->systime;
  71. +            p->itimer[ITIMER_VIRTUAL].startusrtime = p->usrtime;
  72. +            p->itimer[ITIMER_VIRTUAL].timeout =
  73. +                addtimeout(timeleft, itimer_virtual_me);
  74. +        }
  75. +        post_sig(p, SIGVTALRM);
  76. +    }
  77. +    curproc = real_curproc;
  78. +}
  79. +
  80. +/*
  81. + * helper function for t_setitimer: this will be called when the ITIMER_PROF
  82. + * timer goes off
  83. + */
  84. +
  85. +static void
  86. +itimer_prof_me(p)
  87. +    PROC *p;
  88. +{
  89. +    PROC *real_curproc;
  90. +    long timeleft;
  91. +
  92. +    real_curproc = curproc;
  93. +    curproc = p;
  94. +    timeleft = p->itimer[ITIMER_PROF].reqtime
  95. +            - (p->systime - p->itimer[ITIMER_PROF].startsystime)
  96. +            - (p->usrtime - p->itimer[ITIMER_PROF].startusrtime);
  97. +    if (timeleft > 0) {
  98. +        p->itimer[ITIMER_PROF].timeout =
  99. +            addtimeout(timeleft, itimer_prof_me);
  100. +    } else {
  101. +        timeleft = p->itimer[ITIMER_PROF].interval;
  102. +        if (timeleft == 0) {
  103. +            p->itimer[ITIMER_PROF].timeout = 0;
  104. +        } else {
  105. +            p->itimer[ITIMER_PROF].reqtime = timeleft;
  106. +            p->itimer[ITIMER_PROF].startsystime = p->systime;
  107. +            p->itimer[ITIMER_PROF].startusrtime = p->usrtime;
  108. +            p->itimer[ITIMER_PROF].timeout =
  109. +                addtimeout(timeleft, itimer_prof_me);
  110. +        }
  111. +        post_sig(p, SIGPROF);
  112. +    }
  113. +    curproc = real_curproc;
  114. +}
  115. +
  116. +/*
  117. + * t_setitimer(which, interval, value, ointerval, ovalue):
  118. + * schedule an interval timer
  119. + * which is ITIMER_REAL (0) for SIGALRM, ITIMER_VIRTUAL (1) for SIGVTALRM,
  120. + * or ITIMER_PROF (2) for SIGPROF.
  121. + * the rest of the parameters are pointers to millisecond values.
  122. + * interval is the value to which the timer will be reset
  123. + * value is the current timer value
  124. + * ointerval and ovalue are the previous values
  125. + */
  126. +
  127. +long ARGS_ON_STACK
  128. +t_setitimer(which, interval, value, ointerval, ovalue)
  129. +    short which;
  130. +    long *interval;
  131. +    long *value;
  132. +    long *ointerval;
  133. +    long *ovalue;
  134. +{
  135. +    long oldtimer;
  136. +    TIMEOUT *t;
  137. +    void (*handler)() = 0;
  138. +    long tmpold;
  139. +
  140. +    if ((which != ITIMER_REAL) && (which != ITIMER_VIRTUAL)
  141. +        && (which != ITIMER_PROF)) {
  142. +            return EINVFN;
  143. +    }
  144. +
  145. +/* ensure that any addresses specified by the calling process are in that
  146. +   process's address space
  147. +*/
  148. +    if ((interval && (!(valid_address((long) interval))))
  149. +        || (value && (!(valid_address((long) value))))
  150. +        || (ointerval && (!(valid_address((long) ointerval))))
  151. +        || (ovalue && (!(valid_address((long) ovalue))))) {
  152. +            return EIMBA;
  153. +    }
  154. +
  155. +/* see how many milliseconds there were to the timeout */
  156. +    oldtimer = 0;
  157. +
  158. +    if (curproc->itimer[which].timeout) {
  159. +        for (t = tlist; t; t = t->next) {
  160. +            oldtimer += t->when;
  161. +            if (t == curproc->itimer[which].timeout)
  162. +                goto foundtimer;
  163. +        }
  164. +        DEBUG(("Tsetitimer: old timer not found!"));
  165. +        oldtimer = 0;
  166. +foundtimer:
  167. +        ;
  168. +    }
  169. +
  170. +    if (ointerval)
  171. +        *ointerval = curproc->itimer[which].interval;
  172. +    if (ovalue) {
  173. +        if (which == ITIMER_REAL) {
  174. +            *ovalue = oldtimer;
  175. +        } else {
  176. +          tmpold = curproc->itimer[which].reqtime
  177. +            - (curproc->systime - curproc->itimer[which].startsystime);
  178. +          if (which == ITIMER_PROF)
  179. +            tmpold -=
  180. +              (curproc->usrtime - curproc->itimer[which].startusrtime);
  181. +          if (tmpold <= 0)
  182. +            tmpold = 0;
  183. +          *ovalue = tmpold;
  184. +        }
  185. +    }
  186. +    if (interval)
  187. +        curproc->itimer[which].interval = *interval;
  188. +    if (value) {
  189. +/* cancel old timer */
  190. +        if (curproc->itimer[which].timeout)
  191. +            canceltimeout(curproc->itimer[which].timeout);
  192. +        curproc->itimer[which].timeout = 0;
  193. +
  194. +/* add a new timer, to occur in x milliseconds */
  195. +        if (*value) {
  196. +            curproc->itimer[which].reqtime = *value;
  197. +            curproc->itimer[which].startsystime =
  198. +                curproc->systime;
  199. +            curproc->itimer[which].startusrtime =
  200. +                curproc->usrtime;
  201. +            switch (which) {
  202. +                case ITIMER_REAL:
  203. +                    handler = itimer_real_me;
  204. +                    break;
  205. +                case ITIMER_VIRTUAL:
  206. +                    handler = itimer_virtual_me;
  207. +                    break;
  208. +                case ITIMER_PROF:
  209. +                    handler = itimer_prof_me;
  210. +                    break;
  211. +                default:
  212. +                    break;
  213. +            }
  214. +            curproc->itimer[which].timeout =
  215. +                addtimeout(*value, handler);
  216. +        }
  217. +        else
  218. +            curproc->itimer[which].timeout = 0;
  219. +    }
  220. +    return 0;
  221. +}
  222. +
  223.  /*
  224.   * sysconf(which): returns information about system configuration.
  225.   * "which" specifies which aspect of the system configuration is to
  226. @@ -697,4 +902,5 @@
  227.      dos_tab[0x146] = p_setauid;
  228.      dos_tab[0x147] = p_getgroups;
  229.      dos_tab[0x148] = p_setgroups;
  230. +    dos_tab[0x149] = t_setitimer;
  231.  }
  232. diff -u ../old/proc.c ./proc.c
  233. --- ../old/proc.c    Fri Jul 22 03:48:56 1994
  234. +++ ./proc.c    Fri Jul 22 03:15:54 1994
  235. @@ -116,6 +116,15 @@
  236.      p->slices = SLICES(p->pri);
  237.      p->starttime = timestamp;
  238.      p->startdate = datestamp;
  239. +    p->itimer[0].interval = 0;
  240. +    p->itimer[0].reqtime = 0;
  241. +    p->itimer[0].timeout = 0;
  242. +    p->itimer[1].interval = 0;
  243. +    p->itimer[1].reqtime = 0;
  244. +    p->itimer[1].timeout = 0;
  245. +    p->itimer[2].interval = 0;
  246. +    p->itimer[2].reqtime = 0;
  247. +    p->itimer[2].timeout = 0;
  248.  
  249.      ((long *)p->sysstack)[1] = FRAME_MAGIC;
  250.      ((long *)p->sysstack)[2] = 0;
  251. diff -u ../old/proc.h ./proc.h
  252. --- ../old/proc.h    Fri Jul 22 03:48:58 1994
  253. +++ ./proc.h    Wed Jul 20 13:16:44 1994
  254. @@ -69,6 +69,14 @@
  255.      void    (*func) P_((struct proc *)); /* function to call at timeout */
  256.      short    flags;
  257.  } TIMEOUT;
  258. +
  259. +struct itimervalue {
  260. +    TIMEOUT *timeout;
  261. +    long interval;
  262. +    long reqtime;
  263. +    long startsystime;
  264. +    long startusrtime;
  265. +};
  266.  
  267.  #ifndef GENMAGIC
  268.  extern TIMEOUT *tlist;
  269. @@ -224,6 +232,7 @@
  270.  #define    NGROUPMAX    8
  271.      short    ngroups;        /* ts: number of supplementary groups */
  272.      short    ngroup[NGROUPMAX];    /* ts: supplementary groups */
  273. +    struct itimervalue itimer[3];    /* interval timers */
  274.  } PROC;
  275.  
  276.  
  277. diff -u ../old/proto.h ./proto.h
  278. --- ../old/proto.h    Fri Jul 22 03:50:08 1994
  279. +++ ./proto.h    Fri Jul 22 04:15:26 1994
  280. @@ -93,6 +93,7 @@
  281.  long ARGS_ON_STACK p_pause P_((void));
  282.  long ARGS_ON_STACK t_alarm P_((long x));
  283.  long ARGS_ON_STACK t_malarm P_((long x));
  284. +long ARGS_ON_STACK t_setitimer P_((short which, long *interval, long *value, long *ointerval, long *ovalue));
  285.  long ARGS_ON_STACK s_ysconf P_((int which));
  286.  long ARGS_ON_STACK s_alert P_((char *msg));
  287.  void init_dos P_((void));
  288.  
  289. --
  290. entropy -- it's not just a good idea, it's the second law.
  291. Personal mail:      entropy@gnu.ai.mit.edu
  292. MiNT library mail:  entropy@terminator.rs.itd.umich.edu
  293. "what do you have against octal?" -jrb
  294.  
  295.